package com.inspectortime.service.expire;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;

import com.inspectortime.domain.Inspection;
import com.inspectortime.domain.type.InspectionStatus;

public class InspectionAutoExpireAgent extends TimerTask {

	protected static Log log = LogFactory
			.getLog(InspectionAutoExpireAgent.class);
	
	private SessionFactory sessionFactory;
	private ExpirationStrategy strategy;
	
	public InspectionAutoExpireAgent(int initialDelayInMins, int delayBetweenRunsInMins) {
		Timer t = new Timer("AutoExpire", true);
		t.schedule(this, initialDelayInMins * 60 * 1000, delayBetweenRunsInMins * 60 * 1000);
	}

	@Override
	public void run() {

		// Note: We create a session separately in order to avoid confusion with
		// the sessions that are bound to tomcat handler threads
		Session session = sessionFactory.openSession();
		Criteria crit = session.createCriteria(Inspection.class);
		crit.add(Restrictions.eq("inspectionStatus",
				InspectionStatus.QUICK_BOOK));
		List<Inspection> inspections = crit.list();
		int count = 0;
		for (Inspection inspection : inspections) {
			if (strategy.isExpired(inspection)) {
				inspection.setInspectionStatus(InspectionStatus.AUTO_EXPIRED);
				// DONT'T work because it will associate a thread with the current running thread: inspection.save();
				session.update(inspection);
				count++;
			}
		}
		session.flush();
		session.close();
		
		if (!inspections.isEmpty()) {
			log.debug("Found " + inspections.size()
					+ " quick-booked inspections, auto-expired " + count
					+ " of them");			
		}
	}

	

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	public void setStrategy(ExpirationStrategy strategy) {
		this.strategy = strategy;
	}
}
